﻿using System;
using System.Collections.Generic;
using System.Text;

namespace csharpcore7_ch3
{
    class GenericExample1
    {
        static void _Main()
        {
            var stack = new Stack<int>(); //封闭栈
            stack.Push(5);
            stack.Push(10);
            int x = stack.Pop();  //x is 10
            int y = stack.Pop();    //x is 5

            //var stack1 = new Stack<T>();  //Illegal:What is T?

            int x1 = 5;
            int y1 = 10;
            Util.Swap(ref x1, ref y1);
            Console.WriteLine("x=" + x1 +  " y=" +y1);

            var stringstack = new Stack<string>();
            stringstack.Push("str1");
            stringstack.Push("str2");
            
            string s1  = stringstack[0];
            string s2 =  stringstack[1];
            Console.WriteLine("s1=" + s1 + " s2=" + s2);
        }
    }

    /// <summary>
    /// IPopable接口
    /// out修饰符将类类型参数标记为协变参数
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface IPopable<out T> { T Pop(); }

    /// <summary>
    /// 逆变参数
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface IPushable<in T> { void Push(T obj); }
    /// <summary>
    /// 存入类型T实例的泛型栈类型
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class Stack<T> : IPopable<T>,IPushable<T>
    {
        int position;
        T[] data = new T[100];
        public void Push(T obj) => data[position++] = obj;
        public T Pop() => data[position--];


        public Stack<T> Clone()
        {
            Stack<T> clone = new Stack<T>();//Legal
            return clone;
        }

        public T this[int index] => data[index];

        //public Stack<T>(){}   //Illegal
     }
}
